-- 1. Use a fold (choosing the appropriate fold will make your code much simpler) to
-- rewrite and improve upon the asInt function from the earlier section“Explicit Recursion” on page 85.

import Data.Char

-- data Ei a = Right a | Left a

asInt_either :: String -> Either String Int
asInt_either [] = Right 0
asInt_either ['-'] = Right 0
asInt_either ('-':xs) = let val = asInt_either (tail xs)
                        in case val of
                             Left v -> val
                             Right v -> Right (-v)
-- 用foldl
-- asInt_either xs = foldl step (Right 0) xs
--     where step (Right acc) x = if isDigit x
--                                then Right (acc * 10 + digitToInt x)
--                                else Left ("non-digit '" ++ [x] ++ "'")
--           step (Left v) x = Left v

-- 用foldr。注意，与用foldl时step函数参数的顺序不同
asInt_either xs = foldr step (Right 0) xs
    where step x (Right acc) = if isDigit x
                               then Right (acc * 10 + digitToInt x)
                               else Left ("non-digit '" ++ [x] ++ "'")
          step x (Left v) = Left v
                            
